<?php


namespace app\api\service;

use app\api\model\User;
use app\lib\enum\ScopeEnum;
use app\lib\exception\TokenException;
use app\lib\exception\weChatException;
use think\Cache;
use think\Exception;

class Usertoken extends Token {
    protected $code;
    protected $wxAppId;
    protected $wxAppSecret;
    protected $wxLoginUrl;

    public function __construct($code){
        $this->code = $code;
        $this->wxAppId = config('wx.appId');
        $this->wxAppSecret = config('wx.secretId');
        $this->wxLoginUrl = sprintf(config('wx.url'),$this->wxAppId,$this->wxAppSecret,$this->code);
    }

    public function getOpenid(){
        $result = curl_get($this->wxLoginUrl);
//        var_dump($result);
        $wxResult = json_decode($result,true);
        if(empty($wxResult)){
            throw new Exception('获取sessin_key及openID时异常，微信内部错误');
        }else{
//            $loginFail = array_key_exists('errorcode',$wxResult);
//            if($loginFail){
//                $this->processLoginError($wxResult);
//            }else{
//                return $this->grantToken($wxResult);
//            }

            if(isset($wxResult['errorcode']) && $wxResult['errorcode'] =='40029'){
                $this->processLoginError($wxResult);
            }

            return $this->grantToken($wxResult);

        }
    }

    private  function grantToken($data){
        //拿到openid，如果存在则说明该用户存在，不做处理不存在则增加
        //生成令牌，装备 缓存数据， 写入缓存。将令牌返回到客户端
        //openid = 'oRc4e5bh_wKUZc5o0CARO8ntEekY'; session_key = 'J1olM2zQG1r4/Azx3Tpqiw=='
        $openid = $data['openid'];
        $userModel =new User();
        $user = $userModel::getByOpenId($openid);
        if($user){
            $uid = $user->id;
        }else{
            $uid = $this->newUser($openid);
        }

//        $cachedValue = $this->prepareCacheVlue($data,$uid);
//        $token = $this->saveToCache($cachedValue);

        $data['uid'] = $uid;
        //scope = 16 代表App用户的权限数值 32代表CMS(管理员)用户的权限数值
        $data['scope'] = ScopeEnum::USER;
//        $data['scope'] = 14;//人为修改权限为14

        $token = $this->saveToCache($data);
        return $token;

    }

    private function processLoginError($wxResult){
        throw  new weChatException(array(
            'msg' =>$wxResult['errmsg'],
            'errorCode' =>$wxResult['errcode']
        ));
    }

    //用户不存在时，往数据库中插入一条记录
    private  function newUser($openid){
        $userModel = new User();
        $user = $userModel::create(['openid'=>$openid]);
        return $user->id;
    }

    //写入缓存
    private function saveToCache($data){
         //$key 为令牌
         $key = self::generateToken();
         $value = json_encode($data);
         $expire_in = config('setting.token_expire_in');
         //写入缓存，默然写入文件缓存
         $request = cache($key,$value,$expire_in);
         if(!$request){
             throw  new TokenException([
                 'msg'=>'服务器缓存异常',
                 'errorCode' => 10005
             ]);
         }
         return $key;
    }

    //生成身份信息返回给客户端(为了代码的可读性，不要将复杂的逻辑放在一个方法中去处理而写的)
    private  function prepareCacheVlue($data,$uid){
        $cachedValue = $data;
        $cachedValue['uid'] = $uid;
        $cachedValue['scope'] = ScopeEnum::USER;
        return $cachedValue;
    }

    //验证token的有效性
    public static function verifyToken($token){
        $exist = Cache::get($token);
        if($exist){
            return true;
        }else{
            return false;
        }
    }



}























































